package com.lxg.springboot.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.lxg.springboot.entity.Role;
import com.lxg.springboot.entity.User;
import com.lxg.springboot.service.UserService;
import com.lxg.springboot.util.JwtUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author wh1107066
 */
@Controller
public class HelloWorldRestController {
  private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserService userService;

    //-------------------Retrieve All Users--------------------------------------------------------

    @PreAuthorize("hasRole('role1')")
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    @ResponseBody
    public List<User> listAllUsers() {
        List<User> users = userService.findAll();
        if(users.isEmpty()){
            return null;
        }
        return users;
    }

    @PreAuthorize("hasAuthority('role2')")
    @RequestMapping(value = "/role", method = RequestMethod.GET)
    @ResponseBody
    public List<Role> listAllRoles() {
        List<Role> roles = new ArrayList<>();
       roles.add(new Role());
        return roles;
    }


    @PreAuthorize("hasRole('xxx')")
    @RequestMapping(value = "/nopermision", method = RequestMethod.GET)
    @ResponseBody
    public String nopermision() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        logger.info("Authentication信息: {}", authentication);
        return "permision";
    }


    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ResponseBody
    public String hello() {
        return "hello";
    }

    /**
     * jwt 返回的principal是一个字符串， 但是基于form表单提交的是一个数组。 重要！！！
     * 所以这块会取不到userDetails的值
     * @param userDetails
     * @return
     */
    @GetMapping("/user/me")
    @ResponseBody
    public Object user(@AuthenticationPrincipal UserDetails userDetails){
        return userDetails;
    }


    /**
     * jwt 获取Authentication信息
     * 从头部信息中获取额外的参数信息
     * @param principal
     * @return
     */
    @GetMapping("/user/jwt")
    @ResponseBody
    public Authentication jwt(OAuth2Authentication principal, HttpServletRequest request) throws Exception{
        String header = request.getHeader("Authorization");
        if (header != null && header.startsWith("bearer ")) {
            String token = StringUtils.substringAfter(header, "bearer ");
            JsonNode claims = JwtUtils.decodeAndVerify(token);
            Iterator<String> keys = claims.fieldNames();
            while(keys.hasNext()){
                String key = keys.next();
                System.out.println("key键是:"+key);
                JsonNode value = claims.findValue(key);
                System.out.println(value);
            }
            //token内容
            System.out.println("------------------------------------");
            System.out.println(claims);
            System.out.println("----------------------------------->>>>>>>>>>>>");
            //是否有效
            boolean isValid = JwtUtils.checkExp(claims);
            System.out.println(isValid);
            System.out.println("------------------------------------");

        }
        return principal;
    }
}